<?php

/**
 * Device Manager class
 *
 */
 
require_once( 'database-helper.php' );
require_once( 'device-image.php' );

class DeviceManager extends DatabaseHelper {
	
	function __construct() {
		parent::__construct();
	}
	
	/**
	 * Add new device to database
	 *
	 * @return boolean true on success
	 */
	
	function add() {
		if ( $this->isConnected() ) {
			$device = Utils::unMarshalDevice(); //This retrieves data from $_POST
			if ( $device ) {
				$image_filename = $device->storeImage();
				if ( $image_filename ) {
					$this->query( 'INSERT INTO seadmed (seerianumber, mudel, kirjeldus, hind, pilt, qr_id) VALUES("'.$device->getSerial().'", "'.$device->getModel().'","'.$device->getRawDescription().'","'.$device->getRawValue().'","'.$image_filename.'","'.$device->makeQRCode().'")');
				} else {
					$this->query( 'INSERT INTO seadmed (seerianumber, mudel, kirjeldus, hind, qr_id) VALUES("'.$device->getSerial().'", "'.$device->getModel().'","'.$device->getRawDescription().'","'.$device->getRawValue().'","'.$device->makeQRCode().'")');
				}
			}
		}
	}
	
	/**
	 * Modify device in database
	 *
	 * @return boolean true on success
	 */
	 
	function edit() {
		if ( $this->isConnected() ) {
			$device = Utils::unMarshalDevice(); //This retrieves data from $_POST
			if ( $device ) {	
				$image_filename = $device->storeImage();
				if ( $image_filename ) {
					$this->query( 'UPDATE seadmed SET seerianumber = "'.$device->getSerial().'", mudel = "'.$device->getModel().'", kirjeldus = "'.$device->getRawDescription().'", hind = "'.$device->getRawValue().'", qr_id = "'.$device->makeQRCode().'", pilt = "'.$image_filename.'" WHERE seadme_id = "'.$device->getSQL_ID().'"' );
				} else {
					$this->query( 'UPDATE seadmed SET seerianumber = "'.$device->getSerial().'", mudel = "'.$device->getModel().'", kirjeldus = "'.$device->getRawDescription().'", hind = "'.$device->getRawValue().'", qr_id = "'.$device->makeQRCode().'" WHERE seadme_id = "'.$device->getSQL_ID().'"' );
				}
			}
		}
	}
	
	
	/**
	 * Delete device from database
	 *
	 * @return boolean true on success
	 */
	 
	function delete() {
		if ( $this->isConnected() ) {
			//TODO DATA CHECKS
			//TODO DELETE IMAGE
			$device_id = Utils::getRequestDeviceID();
			if ( $device_id ) {
				$device = $this->getDeviceByID( $device_id );
				if ( $device ) {
					$device->deleteImage();
					$this->query( 'DELETE FROM seadmed WHERE seadme_id = "'.$device->getSQL_ID().'"' ); 
				}
			}
		}
	}
	
	/**
	 * Get in storage device count
	 *
	 * @return int
	 */
	
	function getInStorageCount() {
		if ( $this->isConnected() ) {
			$result = $this->query( 'select count(seadme_id) as inStorage from seadmed WHERE seadme_id NOT IN ( SELECT seadmed_id FROM renditud ) OR seadme_id IN ( SELECT seadmed_id FROM renditud WHERE seadmed_id = seadme_id AND seade_kohal = 1 );' );
			if ( $this->hasError() ) {
				return '&#8734';
			}
			$row = mysql_fetch_object( $result );
			return $row->inStorage;
		}
	}
	
	/**
	 * Get out of the storage device count
	 *
	 * @return int
	 */
	
	function getOutStorageCount() {
		if ( $this->isConnected() ) {
			$result = $this->query( 'select count(seadme_id) as outStorage from seadmed, renditud WHERE seadme_id = seadmed_id AND seade_kohal = 0 AND tagastatud = 0;');
			if ( $this->hasError() ) {
				return '&#8734';
			}
			$row = mysql_fetch_object( $result );
			return $row->outStorage;
		}
	}
	
	/**
	 * Get list of all devices
	 *
	 * @return devices list
	 */
	
	//TODO decide if this is needed
	function getAll() {
		$list = array();
		if ( $this->isConnected() ) {
			$result = $this->query( 'SELECT * FROM seadmed ORDER BY mudel ASC' );
			if ( $result ) {			
				while( $row = mysql_fetch_object( $result ) ) {
					$list[] = new Device( $row );
				}
			}
		}
		return $list;
	}
	
	/**
	 * Get list of all in the storage devices
	 *
	 * @return devices list
	 */
	
	function getDevicesInStorage() {
		$list = array();
		if ( $this->isConnected() ) {
			//TODO seperate queries maybe ??
			$result = $this->query( 'SELECT DISTINCT seadme_id, qr_id, seerianumber, mudel, kirjeldus, hind, pilt, tagastatud, seade_kohal FROM seadmed LEFT JOIN renditud ON seadmed_id = seadme_id WHERE seadmed_id IS NULL OR seadmed_id = seadme_id AND seade_kohal = 1 AND tagastatud > 0 ORDER BY mudel ASC' );
			if ( $result ) {			
				while( $row = mysql_fetch_object( $result ) ) {
					$list[] = new Device( $row );
				}
			}
		}
		return $list;
	}
	
	/**
	 * Get list of all out of the storage devices
	 *
	 * @return devices list
	 */
	
	function getDevicesOutStorage() {
		$list = array();
		if ( $this->isConnected() ) {
			$result = $this->query( 'SELECT seadme_id, qr_id, seerianumber, mudel, kirjeldus, hind, pilt, UNIX_TIMESTAMP(renditud_alates) as renditud_alates, tagastamine FROM seadmed, renditud WHERE seadmed_id = seadme_id AND seade_kohal = 0 AND tagastatud = 0 ORDER BY mudel ASC' );
			if ( $result ) {			
				while( $row = mysql_fetch_object( $result ) ) {
					$list[] = new Device( $row );
				}
			}
		}
		return $list;
	}
	
	/**
	 * Get recent most popular devices
	 *
	 * @return devices list
	 */
	
	function getRecentDevices() {
		$list = array();
		if ( $this->isConnected() ) {
			$result = $this->query( 'SELECT seadme_id, qr_id, seerianumber, mudel, kirjeldus, hind, pilt, UNIX_TIMESTAMP(renditud_alates) as renditud_alates, tagastamine, tagastatud, seade_kohal FROM seadmed, renditud WHERE seadmed_id = seadme_id ORDER BY renditud_alates DESC LIMIT 7;' );
			if ( $result ) {			
				while( $row = mysql_fetch_object( $result ) ) {
					$list[ $row->mudel ] = new Device( $row );
				}
			}
		}
		sort( $list );
		return $list;
	}
	
	/**
	 * Return device list as XML
	 *
	 * Outputs also header
	 *
	 * @return XML String
	 */
	
	function asXML( $devices_arr ) {
		header('Content-type: text/xml; charset=utf-8');
		$xml = new SimpleXMLElement( XML_ROOT );
		$devices = $xml->addChild( 'devices' );
		
		if ( $this->isConnected() ) {
			$devices->addChild( 'status', ALL_OK );
			foreach( $devices_arr as $device_obj ) {
				$device = $devices->addChild('device');
				$device->addChild('qr_id', $device_obj->getQRContent() );
				$device->addChild('model', $device_obj->getModel() );
				$device->addChild('serial', $device_obj->getSerial() );
				$device->addChild('value', $device_obj->getValue() );
				$device->addChild('description',  $device_obj->getRawDescription() );
				$device->addChild('image_url', $device_obj->getImageURL() );
			}
		} else {
			$devices->addChild( 'status', ALL_FAILED );
		}
		return $xml->asXML();
	}
	
	/**
	 * Rent device out
	 *
	 * @return boolean true | false
	 */
	
	function rentDevice() {
		if ( $this->isConnected() ) {
			if ( isSet( $_POST['rent_device_ids'] ) ) {
				$qr_ids = $_POST['rent_device_ids'];
				$rentManager = new RentManager();
								
				$devices_sql_ids = array();			
				foreach( $qr_ids as $qr_id ) {
					$device = $this->getDeviceByQR( $qr_id );
					if ( $device && $device->isInStorage() ) {
						//echo "do something, rent out";
						//var_dump($_POST);
						$rent_success = $rentManager->finishRent( $device->getSQL_ID(), $_POST['user_id'], $_POST['return_date'] );
						if ( $rent_success ) {
							$devices_sql_ids[] = $device->getSQL_ID();
							$result = $this->query( 'UPDATE seadmed SET seade_kohal = 0 WHERE qr_id = "'.$this->escape( $device->getQRContent() ).'";' );
							if ( !$this->hasError() ) {
								//echo "Device rented out";
							}
						}
					}
				}
				//If we got some devices ids, add contract
				if ( count( $devices_sql_ids ) > 0 ) {
					return $rentManager->addContract( $_POST['user_id'], $devices_sql_ids );
				}
			}
		}
		return false;
	}
	
	/**
	 * Return device
	 *
	 * @return boolean true | false
	 */
	
	function returnDevice() {
		if ( $this->isConnected() ) {
			if ( isSet( $_POST['device_id'] ) ) {
				$qr_id = strip_tags( $_POST['device_id'] );
				$device = $this->getDeviceByQR( $qr_id );
				if ( $device ) {
					echo "do something, return device";
					$result = $this->query( 'UPDATE seadmed SET seade_kohal = 1 WHERE qr_id = "'.$this->escape( $device->getQRContent() ).'";' );
					if ( !$this->hasError() ) {
						echo "device returned";
					}
				}
			}
		}
		return false;
	}
	
	/**
	 * Get device by QR ID
	 *
	 * @return Device or false
	 */
	
	function getDeviceByQR( $qr_id ) {
		if ( $this->isConnected() ) {
			$result = $this->query( 'SELECT seadme_id, qr_id, seerianumber, mudel, kirjeldus, hind, pilt, seade_kohal FROM seadmed WHERE qr_id = "'.$this->escape( $qr_id ).'" LIMIT 1;' );
			if ( $result ) {
				return new Device( mysql_fetch_object( $result ) );
			}
		}
		return false;
	}
	
	/**
	 * Get device by SQL ID
	 *
	 * @return Device or false
	 */
	
	function getDeviceByID( $device_id ) {
		if ( $this->isConnected() ) {
			$result = $this->query( 'SELECT seadme_id, qr_id, seerianumber, mudel, kirjeldus, hind, pilt, seade_kohal FROM seadmed WHERE seadme_id = "'.$this->escape( $device_id ).'" LIMIT 1;' );
			if ( $result ) {
				return new Device( mysql_fetch_object( $result ) );
			}
		}
		return false;
	}
	
}

/**
 * TLU Haapsalu College Device class
 *
 * @author Raido Kuli 2012
 */

class Device {
	private $model, $serial, $desc, $value, $image, $qr_id, $id, 
			$renditud_alates, $tagastamine, $seade_kohal, $tagastatud = false;
	
	/**
	 * Store some data about device
	 */
	
	function __construct( $sql_obj ) {
		$this->model = $sql_obj->mudel;
		$this->serial = $sql_obj->seerianumber;
		if ( isSet( $sql_obj->kirjeldus ) ) { 
			$this->desc = $sql_obj->kirjeldus;
		}
		$this->value = $sql_obj->hind;
		
		if ( isSet( $sql_obj->pilt ) ) {
			$this->image = $sql_obj->pilt;
		}
		if ( isSet( $sql_obj->qr_id ) ) {
			$this->qr_id = $sql_obj->qr_id;
		}
		if ( isSet( $sql_obj->seadme_id ) ) {
			$this->id = $sql_obj->seadme_id;
		}
		if ( isSet( $sql_obj->renditud_alates ) ) {
			$this->renditud_alates = $sql_obj->renditud_alates;
			$this->tagastamine = $sql_obj->tagastamine;
		}
		if ( isSet( $sql_obj->seade_kohal ) ) {
			$this->seade_kohal = $sql_obj->seade_kohal;
		}
		if ( isSet( $sql_obj->tagastatud ) ) {
			$this->tagastatud = $sql_obj->tagastatud;
		}
	}
	
	/**
	 * Get is in storage flag
	 *
	 * This is used by the recent devices list
	 *
	 * @return boolean true | false
	 */
	
	function isInStorage() {
		return (bool) $this->seade_kohal;
	}
	
	/**
	 * Get rent out date
	 *
	 * @return Date string
	 */
	
	function getOutDate() {
		return strftime( '%A, %d. %B %Y, %H:%M', $this->renditud_alates );
	}
	
	/**
	 * Get assumed return date
	 *
	 * @return Date string
	 */
	
	function getReturnDate( $no_day = false) {
		if ( !$no_day ) {
			return strftime( '%A, %d. %B %Y', $this->tagastamine );
		}
		return strftime( '%d.%m.%Y', $this->tagastamine );
	}
	
	/**
	 * Get actual returned date
	 *
	 * @return Date string
	 */
	
	function getReturnedDate() {
		if ( $this->tagastatud > 0 && $this->isInStorage() ) {
			return strftime( '%A, %d. %B %Y, %H:%M', $this->tagastatud );
		}
		return false;
	}
	
	/**
	 * Get image file name
	 *
	 * @return string filename
	 */
	
	function getImage() {
		if ( @file_exists( 'uploads/'.$this->image ) ) {
			return $this->image;
		}
		return false;
	}
	
	/**
	 * Delete image file
	 *
	 * Called when DeviceManager->delete action
	 */
	
	function deleteImage() {
		if ( ( $img = $this->getImage() ) ) {
			unlink( 'uploads/'.$img );
		}
	}
	
	/**
	 * Get absolute URL to image
	 *
	 * @return string URL
	 */
	
	function getImageURL() {
		if ( ( $image_file = $this->getImage() ) ) {
			return Utils::getWWW().'uploads/'.$image_file;
		}
	}
	
	/**
	 * Get generated QR ID
	 *
	 * @return string qr id
	 */
	 
	function getQRContent() {
		return $this->qr_id;
	}
	
	/**
	 * Get generated QR content
	 *
	 * @return String
	 */
	
	function makeQRCode() {
		return str_replace( ' ', '', $this->getModel() ).'-'.str_replace(' ', '', $this->getSerial() );	
	}
	
	/**
	 * Get device model
	 *
	 * @return string
	 */
	 
	function getModel() {
		return $this->model;
	}
	
	/**
	 * Get device description
	 *
	 * @return string
	 */
	 
	function getDescription() {
		return nl2br($this->desc);
	}
	
	/**
	 * Get raw device description
	 *
	 * @return string
	 */
	 
	function getRawDescription() {
		return $this->desc;
	}
	
	/**
	 * Get device value
	 *
	 * @return string
	 */
	
	function getValue() {
		return money_format('%i', $this->value);
	}
	
	/**
	 * Get device raw value
	 *
	 * @return Double
	 */
	
	function getRawValue() {
		return $this->value;
	}
	
	/**
	 * Get device serial code
	 *
	 * @return string
	 */
	
	function getSerial() {
		return strtoupper( $this->serial );
	}
	
	/**
	 * Get device SQL ID
	 *
	 * @return string
	 */
	 
	function getSQL_ID() {
		return $this->id;
	}
	
	/**
	 * Store uploaded image file on the disk
	 *
	 * @return Stored filename
	 */
	
	function storeImage() {
		$accepted_types = array( 'image/png', 'image/jpeg' );
		if ( isSet( $_FILES['device_image_uploaded'] ) ) {
			$image = new DeviceImage( $_FILES['device_image_uploaded'] );
			if ( $image->getError() === UPLOAD_ERR_OK && in_array( $image->getType(), $accepted_types ) ) {
				if ( $this->getImage() ) {
					$this->deleteImage();
				}
				$image->resize();
				//Save and return saved filename or false
				return $image->save();
			}
		}
		return false;
	}
	
	/**
	 * Get JSON encoded device data
	 *
	 * @return JSON
	 */
	
	function getJSON() {
		$data = array( 'id' => $this->getQRContent(), 'model' => $this->getModel(), 'value' => $this->getRawValue(), 'image' => $this->getImage(), 
					'serial' => $this->getSerial(), 'description' => $this->getRawDescription() );
		header('Content-type: text/json; charset=utf-8');
		return json_encode( $data );
	}
	
}


?>